﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Common.OjbectPool
{
    /// <summary>
    ///  An interface defining life-cycle methods for instances to be served by an
    /// <see cref="IObjectPool"/>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IPooledObjectFactory<T>  
    {

        /// <summary>
        /// Create an instance that can be served by the pool and wrap it in a
        ///<see cref="IPooledOjbect"/>to be managed by the pool.
        /// </summary>
        /// <returns>wrapping an instance that can be served by the pool</returns>
        ///<exception cref="Exception">
        ///  if there is a problem creating a new instance,this
        /// will be propagated to the code requesting an object.
        /// </exception>  
        IPooledObject<T> MakeObject();

        /// <summary>
        /// Destroys an instance no longer needed by the pool.
        /// It is important for implementations of this method to be aware tha
        /// is no guarantee about what state <c>p</c> will be in and t
        /// implementation should be prepared to handle unexpected errors.
        /// <p>
        /// Also, an implementation must take in to consideration that instanc
        /// to the garbage collector may never be destroyed.
        /// </p>
        /// </summary>
        /// <param name="p">a <c>IPooledObject</c> wrapping the instance to be destroyed</param>
        /// <exception cref="Exception">should be avoided as it may be swallowed by  the pool implementation.</exception>
        /// <seealso cref="ValidateObject"/>
        /// <seealso cref="IObjectPool#InvalidateObject"/>
        void DestroyObject(IPooledObject<T> p);



        /// <summary>
        /// Ensures that the instance is safe to be returned by the pool.
        /// </summary>
        /// <param name="p">a <c>IPooledObject</c> wrapping the instance to be validated</param>
        /// <returns>
        /// <c>false</c> if <c>p</c> is not valid and should
        /// be dropped from the pool, <c>true</c> otherwise.
        /// </returns>
        Boolean ValidateObject(IPooledObject<T> p);



        /// <summary>
        ///  Reinitialize an instance to be returned by the pool.
        /// </summary>
        /// <param name="p">a <c>IPooledObject</c> wrapping the instance to be activated</param>
        /// <exception cref="Exception">if there is a problem activating <c>p</c>, this exception may be swallowed by the pool.</exception>
        ///<seealso cref="DestroyObject"/>
        void ActivateObject(IPooledObject<T> p);
        
        /// <summary>
        /// Uninitialize an instance to be returned to the idle object pool.
        /// </summary>
        /// <param name="p">a <c>IPooledObject</c>  wrapping the instance to be passivated</param>
        /// <exception cref="Exception">if there is a problem passivating <c>p</c>,this exception may be swallowed by the pool.</exception>
        ///<seealso cref="DestroyObject"/>
        void PassivateObject(IPooledObject<T> p);
    }

}
